package com.demo.cms.service;

import java.util.List;

import com.demo.cms.model.Category;
import com.demo.cms.service.exception.CategoryCreateException;
import com.demo.core.dao.base.support.ResultSearchResult;
import com.demo.core.dao.base.support.SearchArgumentSupport;
import com.demo.core.model.support.AdjacencyListModel;

/**
 * 栏目服务Service接口
 * 
 * @author ryuu.kk
 *
 */
public interface CategoryService {

	/**
	 * 创建栏目
	 * @param category 栏目模型
	 * @return 外键ID
	 */
	Long save(Category category) throws CategoryCreateException;;
	
	/**
	 * 栏目是否存在
	 * @param id 外键ID
	 * @return 栏目是否存在
	 */
	boolean exists(Long id);
	
	/**
	 * 删除栏目数据
	 * 保留栏目相关的文章相关信息
	 * @param id 外键ID
	 */
	void delete(Long id);
	
	/**
	 * 删除栏目数据
	 * 如果级联删除,则一并删除文章相关信息
	 * @param categoryId 栏目ID
	 * @param cascade 是否级联删除
	 * @deprecated 使用数据库级联删除
	 */
	@Deprecated
	void delete(Long categoryId, boolean cascade);
	
	/**
	 * 更新栏目模型信息
	 * 注意,如果其中包含栏目内容和栏目的扩展属性，将同时更新。
	 * @param id 栏目外键ID
	 * @param category 栏目模型(复合模型)
	 */
	void update(Long categoryId, Category category);
	
	/**
	 * 更新许可
	 * @param categoryId 栏目ID
	 * @param isPermission 许可标志
	 */
	void updatePermission(Long categoryId, boolean isPermission);
	
	/**
	 * 更新草稿状态
	 * @param categoryId 栏目ID
	 * @param isDraft 是否草稿
	 */
	void updateDraft(Long categoryId, boolean isDraft);

	/**
	 * 更新项目状态
	 * @param categoryId 栏目ID
	 * @param category 栏目模型
	 */
	void updateStatus(Long categoryId, Category category);
	
	/**
	 * 查找栏目模型对象
	 * <p>包含栏目内容和扩展属性</p>
	 * @param id 外键ID
	 * @return 栏目模型
	 */
	Category find(Long id);
	
	/**
	 * 通过栏目地址查找栏目模型对象
	 * @param path 栏目地址
	 * @return 栏目模型
	 */
	Category find(String path);
	
	/**
	 * 查找频道中的根栏目
	 * 频道ID都有一个根栏目ID
	 * @param channelId
	 * @return 该频道的Category root节点
	 */
	Category findRoot(Long channelId);
	
	/**
	 * 查找所有频道的栏目根节点
	 * 该方法取得的root节点不依赖与任何频道，是所有节点的超级父亲
	 * @return Category root节点
	 */
	Category findRoot();
	
	/**
	 * 通过频道ID查询栏目模型列表
	 * @param channelId 频道ID
	 * @return List<Category> 栏目模型列表
	 */
	List<Category> findList(Long channelId);
	
	/**
	 * 通过频道ID和栏目父ID查询栏目列表
	 * @param channelId 频道ID
	 * @param pid 栏目父ID
	 * @return List<Category> 栏目模型列表
	 */
	List<Category> findList(Long channelId, Long pid);
	
	/**
	 * 通过频道ID查询栏目模型列表
	 * @param categoryId 栏目ID
	 * @param i18n 国际化CODE
	 * @return 栏目模型列表
	 */
	List<Category> findList(Long channelId, String i18n);

	/**
	 * 通过站点ID和国际化CODE查询所有栏目
	 * @param categoryId 栏目ID
	 * @param i18n 国际化CODE
	 * @return 栏目模型列表
	 */
	List<Category> findAll(Long siteId, String i18n);

	/**
	 * 根据频道ID查询所有树形栏目
	 * 查询结果是频道的栏目树(从树根开始)
	 * @param channelId 频道ID
	 * @return AdjacencyListModel 邻接树形结构模型
	 */
	AdjacencyListModel queryRootTree(Long channelId);

	/**
	 * 根据栏目ID和层级level查询树形结构的栏目
	 * @param categoryId 栏目ID
	 * @param level 层级ID(即树的深度n{0,n})
	 * @return AdjacencyListModel 邻接树形结构模型
	 */
	AdjacencyListModel queryTree(Long categoryId, int... level);
	
	/**
	 * 根据栏目ID和层级level查询树形结构的栏目
	 * @param categoryPath 栏目路径
	 * @param level 层级ID(即树的深度n{0,n})
	 * @return AdjacencyListModel 邻接树形结构模型
	 */
	AdjacencyListModel queryTree(String categoryPath, int... level);
	
	/**
	 * 根据栏目ID和层级level查询树形结构的栏目
	 * @param categoryId 栏目ID
	 * @param isReverse 是否反向查找(叶子-根)
	 * @param level 层级ID(即树的深度n{0,n})
	 * @return AdjacencyListModel 邻接树形结构模型
	 */
	AdjacencyListModel queryTree(Long categoryId, Boolean isReverse, int... level);
	
	/**
	 * 根据栏目ID和层级level查询树形结构的栏目
	 * @param categoryPath 栏目路径
	 * @param isReverse 是否反向查找(叶子-根)
	 * @param level 层级ID(即树的深度n{0,n})
	 * @return AdjacencyListModel 邻接树形结构模型
	 */
	AdjacencyListModel queryTree(String categoryPath, Boolean isReverse, int... level);
	
	/**
	 * 通过栏目的父亲ID和频道ID查询第二层子栏目(相对PID)
	 * @param channelId 频道ID
	 * @param categoryId 栏目PID
	 * @param firstResult 起始节点
	 * @param maxResults 最大条目
	 * @return 分页查询对象
	 * 目前查询栏目还未用到.
	 */
	ResultSearchResult<Category> search(Long channelId, Long categoryId,
			int firstResult, int maxResults);
	
	/**
	 * 通过栏目的父亲ID和频道ID查询第二层子栏目(相对PID)
	 * @param channelId 频道ID
	 * @param categoryId 栏目PID
	 * @param firstResult 起始节点
	 * @param maxResults 最大条目
	 * @return 分页查询对象
	 */
	ResultSearchResult<Category> search(Long channelId, Long pid, SearchArgumentSupport args);
	
	/**
	 * 外部栏目查询
	 * @param ssid (channelId) 频道ID
	 * @return 栏目列表
	 */
	List<Category> _findList(String ssid);
	
	/**
	 * 更新栏目的信息
	 * @param categoryId 栏目ID
	 * @param category 栏目模型
	 * @param isWhole 是否对整个栏目进行更新
	 */
	void update(Long categoryId, Category category, boolean isWhole);

//	/**
//	 * 通过栏目ID查新栏目信息和所有内容
//	 * 该方法为一个复合查询方法
//	 * 栏目模型中包含内容模型和扩展属性模型
//	 * @param id 栏目外键ID
//	 * @return 栏目模型对象
//	 */
//	Category query(Long id);
//
//	/**
//	 * 通过栏目ID查新栏目信息和指定索引内容
//	 * 该方法为一个复合查询方法
//	 * 栏目模型中包含内容模型和扩展属性模型
//	 * @param id 栏目外键ID
//	 * @param index 栏目内容索引
//	 * @return 栏目模型对象
//	 */
//	Category query(Long id, int index);
//
//	/**
//	 * 通过栏目ID查新栏目信息和指定索引内容
//	 * 该方法为一个复合查询方法
//	 * 栏目模型中包含内容模型和扩展属性模型
//	 * @param id 栏目外键ID
//	 * @param index 栏目内容索引
//	 * @param nameList 扩展属性名(为空则查询所有)
//	 * @return 栏目模型对象
//	 */
//	Category query(Long id, int index, List<String> nameList);
}
